<template>
  <v-form
    ref="formComponent"
    v-model="valid"
    :lazy-validation="formConfigAttributes.lazyValidation"
    :class="formConfigAttributes.class"
  >
    <!-- <v-container :fluid="formConfigAttributes.fluid"> -->
    <v-row v-if="formContentShow">
      <template v-for="item in formItemConfig">
        <v-col
          v-if="item.formShow"
          :key="item.id"
          :md="item.cols"
          :lg="item.cols"
          :xl="item.cols"
          class="customFormCol"
          cols="12"
          sm="12"
          xs="12"
        >
          <div v-if="isFormLabelShow" class="customFormColLabel">
            {{ item.label }}
          </div>

          <form-content
            v-model="form[item.prop]"
            class="customFormColContent"
            :class="formLayout === 'l&r' ? 'UnshowDefaultLabel' : 'insideFormItemStyle'"
            :config-item="item"
            @input="$emit('input', form[item.prop])"
          >
          </form-content>
        </v-col>
      </template>
    </v-row>
    <form-operation
      v-if="formOperationShow"
      :form-operation="formConfig.formOperation"
      @formCancel="formCancel"
      @formSave="formSave"
      @buttonListMethodCB="buttonListMethodCB"
    ></form-operation>
    <!-- </v-container> -->
  </v-form>
</template>

<script>
import { descNumber } from 'utils/arraySort'
import { isEmptyValue } from '@/utils/tools'
import FormContent from './FormContent.vue'
import FormOperation from './FormOperation.vue'
import { IsPC } from '@/utils/judgePC'

export default {
  // 表单主要组件
  name: 'FormComponent',

  // 引用组件
  components: { FormContent, FormOperation },

  // 父组件传递的props
  props: {
    // 表单
    formData: { type: Object, default: () => {} },
    // 表单配置
    formConfig: { type: Object, default: () => {} }
  },

  data() {
    return {
      // 表格有效值
      valid: true,
      // 表单配置属性
      formConfigAttributes: this.formConfig.formConfigAttributes || {},
      // 表单子项配置
      formItemConfig: this.formConfig.itemConfig,
      // 表单
      form: this.formData,
      // 表单布局方式 左右 l&r 内含 inside
      // formLayout: this.formConfig.formLayout || 'l&r'
      isPC: IsPC()
    }
  },

  computed: {
    formContentShow() {
      return this.formAttributesDefinedMode('formContentShow')
    },

    formOperationShow() {
      return this.formAttributesDefinedMode('formOperationShow')
    },

    /**
     * 左右布局时 显示 label, 否则不显示 label
     */
    isFormLabelShow() {
      return this.formLayout === 'l&r'
    },

    /**
     * 设置 formLayout 的布局方式
     */
    formLayout() {
      /**
       * 参数定义方式 defined mode: formConfig.formLayout / formConfig.formConfigAttributes.formLayout
       */
      const formLayoutOutside = this.formConfig.formLayout
      const formLayoutInside = this.formConfig.formConfigAttributes.formLayout
      if (isEmptyValue(formLayoutOutside)) {
        return isEmptyValue(formLayoutInside) ? 'l&r' : formLayoutInside
      } else {
        return isEmptyValue(formLayoutInside) ? formLayoutOutside : formLayoutInside
      }
    }
  },

  created() {
    // 设置表单配置属性
    this.setFormConfigAttributes()

    this.setFormItemShow()
    isEmptyValue(this.formConfig.formOperation) && (this.formConfig.formOperation = {})
  },

  mounted() {
    // formLayout: 'l&r', 动态设置 label 宽度
    this.setFormLayoutLabelWidth()

    // formLayout: 'l&r', init input placeholder
    // this.setFormItemInitPlaceholder()
  },

  methods: {
    /**
     * 设置表单组件配置属性
     * 使用方法: formConfig: { formConfigAttributes: { } }
     */
    setFormConfigAttributes() {
      // console.log(this.formConfig.formConfigAttributes)
      const defualtConifg = { lazyValidation: true, fluid: true }
      // console.log(Object.assign(defualtConifg, this.formConfig.formConfigAttributes))
      this.formConfig.formConfigAttributes = Object.assign(defualtConifg, this.formConfig.formConfigAttributes)
      this.formConfigAttributes = { ...this.formConfig.formConfigAttributes }
    },

    // 设置表单左右布局 formLayout: l&r 时 label的动态宽度
    setFormLayoutLabelWidth() {
      console.log(1)
      if (this.formLayout === 'l&r') {
        // 1. 获取所有表单项的 label 节点
        const labelNodeList = document.getElementsByClassName('customFormColLabel')
        console.log(labelNodeList)
        // 2. 定义所有 label 宽度集 并添加宽度数据
        let labelWidthList = []
        labelNodeList.forEach(node => labelWidthList.push(node.clientWidth))
        // 3. 降序排序 所有宽度数据
        labelWidthList = labelWidthList.sort(descNumber)
        // 4. 操作 dom 修改宽度 并添加 间隔
        const maxClientWidth = labelWidthList[0]
        labelNodeList.forEach(node => (node.style.width = maxClientWidth + 'px'))
      }
    },

    // 设置 fromLayout: 'l%r' 时,定义初始化placeholder
    setFormItemInitPlaceholder() {
      if (this.formLayout === 'l&r') {
        const formContentNodeList = document.getElementsByClassName('customFormColContent')
        // console.log('formContentNodeList', formContentNodeList)
        const selectNodeList = []
        formContentNodeList.forEach(node => {
          const selectElement = node.getElementsByTagName('input')
          selectElement[0].setAttribute('placeholder', 'dwadwadwa')
          selectElement[0].placeholder = 'dwadw'
          selectNodeList.push(selectElement)
          // console.log('selectElement', selectElement[0].placeholder)
        })
        console.log('selectNodeList', selectNodeList)
      }
    },

    setFormItemShow() {},

    /**
     * 定义表单配置属性是否定义，设置默认值
     * @param { 父组件中定义的属性名 } formDefinedAttribute
     * @returns { Boolean } true or false
     * 1.获取参数的定义路径
     *   formOutDefinedAttribute    参数定义在 formConfig 下
     *   formInsideDefinedAttribute 参数定义在 formConfig.formConfigAttributes 下
     *
     * 2.formOutDefinedAttribute        无值
     *   2.1 formInsideDefinedAttribute 无值 -> 返回 true
     *   2.2 formInsideDefinedAttribute 有值 -> 返回 formInsideDefinedAttribute
     *
     * 3.formOutDefinedAttribute        有值
     *   3.1 formInsideDefinedAttribute 无值 -> 返回 formOutDefinedAttribute
     *   3.2 formInsideDefinedAttribute 有值
     *       转换类型 formOutDefinedAttribute, formInsideDefinedAttribute 真假, 返回值是 true 的配置
     */
    formAttributesDefinedMode(formDefinedAttribute) {
      const formOutDefinedAttribute = this.formConfig[formDefinedAttribute]
      const formInsideDefinedAttribute = this.formConfig.formConfigAttributes[formDefinedAttribute]
      if (isEmptyValue(formOutDefinedAttribute)) {
        return isEmptyValue(formInsideDefinedAttribute) ? true : formInsideDefinedAttribute
      } else {
        const booleanFlag = Boolean(formOutDefinedAttribute) || Boolean(formInsideDefinedAttribute)
        return isEmptyValue(formInsideDefinedAttribute) ? formOutDefinedAttribute : booleanFlag
      }
    },

    // 取消操作
    formCancel(el) {
      this.$emit('formCancel', el)
    },
    // 保存操作
    formSave(el) {
      this.$emit('formSave', el)
    },

    buttonListMethodCB(methodName, el) {
      // console.log(methodName, el)
      this.$emit('formBtnCB', methodName, el)
    }
  }
}
</script>

<style lang="scss" scoped>
// 表单通用样式
.customFormCol {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;

  .customFormColLabel {
    display: flex;
    justify-content: flex-end;
  }

  .customFormColContent {
    flex: 1;
  }
}
</style>

<style lang="scss" scoped>
// 左右布局时 表单子项样式
.UnshowDefaultLabel {
  ::v-deep {
    // textField 样式
    .v-text-field {
      .v-text-field__slot {
        label {
          display: none;
        }
      }
    }
  }
}
</style>

<style lang="scss" scoped>
// 左右布局时 表单子项样式
.insideFormItemStyle {
  ::v-deep {
    // textField 样式
    .v-text-field {
      .v-text-field__slot {
        label {
          text-align: left;
        }
      }
    }
  }
}
</style>
